﻿using System;
using System.Windows;

using Belphegor.Dynamics;
using Belphegor.Routines;
using Zeta;
using Zeta.CommonBot;
using Zeta.Internals.Actors;
using Zeta.Navigation;
using Zeta.TreeSharp;

namespace Belphegor
{
    public class Belphegor : CombatRoutine
    {
        public Belphegor()
        {
            Instance = this;
        }

        public static Belphegor Instance { get; private set; }

        #region Overrides of CombatRoutine

        private Composite _combat;
        private Composite _buff;

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public override void Dispose()
        {
            Pulsator.OnPulse -= SetBehaviorPulse;
        }

        /// <summary>
        /// Gets the name of this <see cref="CombatRoutine"/>.
        /// </summary>
        /// <remarks>Created 2012-04-03</remarks>
        public override string Name { get { return "Belphegor All-in-One"; } }

        /// <summary>
        /// Gets the configuration window.
        /// </summary>
        /// <remarks>Created 2012-04-03</remarks>
        public override Window ConfigWindow { get { return null; } }

        /// <summary>
        /// Gets the class.
        /// </summary>
        /// <remarks>Created 2012-04-03</remarks>
        public override ActorClass Class
        {
            get
            {
                if (!ZetaDia.IsInGame || ZetaDia.IsLoadingWorld)
                {
                    // Return none if we are oog to make sure we can start the bot anytime.
                    return ActorClass.Invalid;
                }
                
                return ZetaDia.Me.ActorClass;
            }
        }

        public override float DestroyObjectDistance
        {
            get
            {
                switch (Class)
                {
                    case ActorClass.Barbarian:
                    case ActorClass.Monk:
                        return 10f;
                    case ActorClass.DemonHunter:
                    case ActorClass.Wizard:
                    case ActorClass.WitchDoctor:
                        return 30f;
                    default:
                        return 10f;

                }
            }
        }

        public override SNOPower DestroyObjectPower { get { return ZetaDia.Me.GetHotbarPowerId(HotbarSlot.HotbarMouseLeft); } }

        /// <summary>
        /// Gets me.
        /// </summary>
        /// <remarks>Created 2012-05-08</remarks>
        public DiaActivePlayer Me { get { return ZetaDia.Me; } }

        /// <summary>
        /// Initializes this <see cref="CombatRoutine"/>.
        /// </summary>
        /// <remarks>Created 2012-04-03</remarks>
        public override void Initialize()
        {
            GameEvents.OnLevelUp += Monk.MonkOnLevelUp;
            GameEvents.OnLevelUp += Wizard.WizardOnLevelUp;
            GameEvents.OnLevelUp += WitchDoctor.WitchDoctorOnLevelUp;
            GameEvents.OnLevelUp += DemonHunter.DemonHunterOnLevelUp;
            GameEvents.OnLevelUp += Barbarian.BarbarianOnLevelUp;

            if (!CreateBehaviors())
            {
                BotMain.Stop();
                return;
            }

            _lastClass = Class;
            Pulsator.OnPulse += SetBehaviorPulse;
            //Navigator.PlayerMover = new BelphegorPlayerMover();

            Logger.Write("Behaviors created");
        }

        /// <summary>
        /// Gets the combat behavior.
        /// </summary>
        /// <remarks>Created 2012-04-03</remarks>
        public override Composite Combat { get { return _combat; } }
        public override Composite Buff { get { return _buff; } }

        private ActorClass _lastClass = ActorClass.Invalid;
        public void SetBehaviorPulse(object sender, EventArgs args)
        {
            if (ZetaDia.IsInGame && !ZetaDia.IsLoadingWorld && ZetaDia.Me != null && ZetaDia.Me.CommonData != null)
            {
                if (_combat == null || ZetaDia.Me.IsValid && Class != _lastClass)
                {
                    if (!CreateBehaviors())
                    {
                        BotMain.Stop();
                        return;
                    }

                    Logger.Write("Behaviors created");
                    _lastClass = Class;
                }
            }
        }

        public bool CreateBehaviors()
        {
            int count;
            _combat = CompositeBuilder.GetComposite(Class, BehaviorType.Combat, out count);

            if (count == 0 || _combat == null)
            {
                Logger.Write("Combat support for " + Class + " is not currently implemented.");
                return false;
            }

            _buff = CompositeBuilder.GetComposite(Class, BehaviorType.Buff, out count);
            if (count == 0 || _buff == null)
            {
                Logger.Write("Buff support for " + Class + " is not currently implemented.");
            }

            return true;
        }

        #endregion
    }
}
